package com.guigu.eduservice.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guigu.eduservice.entity.*;
import com.guigu.eduservice.mapper.EquipmentImageMapper;
import com.guigu.eduservice.mapper.EquipmentMapper;
import com.guigu.eduservice.mapper.EquipmentVideoMapper;
import com.guigu.eduservice.mapper.EquipmentTypeMapper;
import com.guigu.eduservice.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.eduservice.vo.AuditVo;
import com.guigu.eduservice.vo.EqVo;
import com.guigu.eduservice.vo.EquipmentVo;
import com.guigu.eduservice.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.awt.image.VolatileImage;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备表（存储卖家发布的二手机械信息） 服务实现类
 * </p>
 *
 * @author janecraft
 * @since 2025-09-27
 */
@Service
public class EquipmentServiceImpl extends ServiceImpl<EquipmentMapper, Equipment> implements EquipmentService {

    @Autowired
    private EquipmentMapper equipmentMapper;
    @Autowired
    private EquipmentTypeMapper equipmentTypeMapper;
    @Autowired
    private EquipmentImageService equipmentImageService;
    @Autowired
    private EquipmentImageMapper equipmentImageMapper;
    @Autowired
    private EquipmentVideoMapper equipmentVideoMapper;
    @Autowired
    private EquipmentVideoService equipmentVideoService;
    @Autowired
    private EquipmentTypeService equipmentTypeService;
    @Autowired
    private OrderService orderService;

    //设备分页
    @Override
    public PageInfo<Equipment> page(Integer pageNum, Integer pageSize, EqVo vo) {
        // 1. 分页参数合法性校验（避免无效分页，如pageNum=0、pageSize=-1）
        if (pageNum == null || pageNum < 1) {
            pageNum = 1; // 默认查询第1页
        }
        if (pageSize == null || pageSize < 1 || pageSize > 100) {
            pageSize = 10; // 默认每页10条，最大限制100条（避免性能问题）
        }

        // 2. 启动PageHelper分页（必须在查询SQL执行前调用，且仅对下一次查询生效）
        PageHelper.startPage(pageNum, pageSize);

        // 3. 构建Lambda查询条件（仅在筛选条件非空时添加，避免无效SQL）
        LambdaQueryWrapper<Equipment> wrapper = new LambdaQueryWrapper<>();

        // 3.1 非空判断：先判断VO是否为null，再判断具体字段是否非空且非空字符串
        if (vo != null) {
            // 设备类型筛选：仅当equipmentTypeVo非空且不是空字符串时，才添加模糊查询
            // 逻辑：仅当typeIdVo不为null时，才添加筛选（Long类型无需trim，避免空指针）
            if (vo.getEquipmentTypeVo() != null) {
                wrapper.eq(Equipment::getTypeId, vo.getEquipmentTypeVo()); // 匹配数据库typeId字段
            }
            // 品牌筛选：同上（trim()去除前后空格，避免用户输入空格导致的无效查询）
            if (vo.getBrand() != null && !vo.getBrand().trim().isEmpty()) {
                wrapper.like(Equipment::getBrand, vo.getBrand().trim());
            }
            // 状态筛选：同上
            if (vo.getStatus() != null && vo.getStatus()!=4){
                wrapper.eq(Equipment::getStatus, vo.getStatus());
            }else if (vo.getStatus() == 4|| vo.getStatus() == null){
                wrapper.ne(Equipment::getStatus, 0);
            }
            // 设备类型筛选：同上
            if (vo.getTypeId() != null && vo.getTypeId() != 0) {
                wrapper.eq(Equipment::getTypeId, vo.getTypeId());
            }
            // 设备类型筛选：同上
            if (vo.getSonTypeId() != null && vo.getSonTypeId() != 0) {
                wrapper.eq(Equipment::getTypeId, vo.getSonTypeId());
            }

            // 3.3 排序：按发布时间倒序（最新发布的设备排在前面）
            wrapper.orderByDesc(Equipment::getReleaseTime);
        }



        // 4. 执行查询（PageHelper会自动拦截此查询，添加分页SQL） 拿到设备列表
        List<Equipment> equipmentList = equipmentMapper.selectList(wrapper);

        // 4.1. 收集所有设备ID，一次性查询所有图片
        List<Long> equipmentIds = equipmentList.stream()
                .map(Equipment::getEquipmentId)
                .collect(Collectors.toList());

        // 如果设备ID列表为空，直接返回空的图片映射，避免无效查询
        if (equipmentIds.isEmpty()) {
            // 为每个设备设置空图片列表
            equipmentList.forEach(equipment -> equipment.setEquipmentImages(Collections.emptyList()));
            // 直接返回分页结果
            return new PageInfo<>(equipmentList);
        }
        QueryWrapper<EquipmentImage> imageWrapper = new QueryWrapper<>();
        imageWrapper.in("equipment_id", equipmentIds)
                .orderByDesc("sort");

        // 4.2一次性查询所有相关图片
        List<EquipmentImage> allImages = equipmentImageMapper.selectList(imageWrapper);

        // 4.3. 将图片按设备ID分组，便于快速查找
        Map<Long, List<EquipmentImage>> imageMap = allImages.stream()
                .collect(Collectors.groupingBy(EquipmentImage::getEquipmentId));

        // 4.4. 为每个设备设置图片
        for (Equipment equipment : equipmentList) {
            // 从Map中获取当前设备的图片列表（不存在则为空列表）
            List<EquipmentImage> images = imageMap.getOrDefault(equipment.getEquipmentId(), Collections.emptyList());
            equipment.setEquipmentImages(images);
        }

        // 查询所有设备的列表的类型
        for (Equipment equipment : equipmentList){
            Long typeId = equipment.getTypeId();
            EquipmentType equipmentType = equipmentTypeMapper.selectById(typeId);
            equipment.setEquipmentType(equipmentType);
        }

        // 5. 封装分页结果（PageInfo会自动计算总条数、总页数等）
        PageInfo<Equipment> pageInfo = new PageInfo<>(equipmentList);

        return pageInfo;
    }

    @Override
    public PageInfo<Equipment> EquipmentPage(Integer pageNum, Integer pageSize, EqVo vo) {
        // 分页参数合法性校验（避免无效分页，如pageNum=0、pageSize=-1）
        if (pageNum == null || pageNum < 1) {
            pageNum = 1; // 默认查询第1页
        }
        if (pageSize == null || pageSize < 1 || pageSize > 100) {
            pageSize = 10; // 默认每页10条，最大限制100条（避免性能问题）
        }

        // 启动PageHelper分页（必须在查询SQL执行前调用，且仅对下一次查询生效）
        PageHelper.startPage(pageNum, pageSize);

        // 构建Lambda查询条件（仅在筛选条件非空时添加，避免无效SQL）
        LambdaQueryWrapper<Equipment> wrapper = new LambdaQueryWrapper<>();

        // 非空判断：先判断VO是否为null，再判断具体字段是否非空且非空字符串
        if (vo != null) {
            // 设备类型筛选：仅当equipmentTypeVo非空且不是空字符串时，才添加模糊查询
            // 逻辑：仅当typeIdVo不为null时，才添加筛选（Long类型无需trim，避免空指针）
            if (vo.getEquipmentTypeVo() != null) {
                wrapper.eq(Equipment::getTypeId, vo.getEquipmentTypeVo()); // 匹配数据库typeId字段
            }
            // 品牌筛选：同上（trim()去除前后空格，避免用户输入空格导致的无效查询）
            if (vo.getBrand() != null && !vo.getBrand().trim().isEmpty()) {
                wrapper.like(Equipment::getBrand, vo.getBrand().trim());
            }
            // 状态筛选
            if (vo.getStatus() != null){
                wrapper.eq(Equipment::getStatus, vo.getStatus());
            }
            // 设备类型筛选
            if (vo.getTypeId() != null && vo.getTypeId() != 0) {
                wrapper.eq(Equipment::getTypeId, vo.getTypeId());
            }

            // 3.3 排序：按发布时间倒序（最新发布的设备排在前面）
            wrapper.orderByDesc(Equipment::getReleaseTime);
        }



        // 4. 执行查询（PageHelper会自动拦截此查询，添加分页SQL） 拿到设备列表
        List<Equipment> equipmentList = equipmentMapper.selectList(wrapper);

        // 4.1. 收集所有设备ID，一次性查询所有图片
        List<Long> equipmentIds = equipmentList.stream()
                .map(Equipment::getEquipmentId)
                .collect(Collectors.toList());

        // 如果设备ID列表为空，直接返回空的图片映射，避免无效查询
        if (equipmentIds.isEmpty()) {
            // 为每个设备设置空图片列表
            equipmentList.forEach(equipment -> equipment.setEquipmentImages(Collections.emptyList()));
            // 直接返回分页结果
            return new PageInfo<>(equipmentList);
        }
        QueryWrapper<EquipmentImage> imageWrapper = new QueryWrapper<>();
        imageWrapper.in("equipment_id", equipmentIds)
                .orderByDesc("sort");

        // 4.2一次性查询所有相关图片
        List<EquipmentImage> allImages = equipmentImageMapper.selectList(imageWrapper);

        // 4.3. 将图片按设备ID分组，便于快速查找
        Map<Long, List<EquipmentImage>> imageMap = allImages.stream()
                .collect(Collectors.groupingBy(EquipmentImage::getEquipmentId));

        // 4.4. 为每个设备设置图片
        for (Equipment equipment : equipmentList) {
            // 从Map中获取当前设备的图片列表（不存在则为空列表）
            List<EquipmentImage> images = imageMap.getOrDefault(equipment.getEquipmentId(), Collections.emptyList());
            equipment.setEquipmentImages(images);
        }

        // 查询所有设备的列表的类型
        for (Equipment equipment : equipmentList){
            Long typeId = equipment.getTypeId();
            EquipmentType equipmentType = equipmentTypeMapper.selectById(typeId);
            equipment.setEquipmentType(equipmentType);
        }

        // 5. 封装分页结果（PageInfo会自动计算总条数、总页数等）
        PageInfo<Equipment> pageInfo = new PageInfo<>(equipmentList);

        return pageInfo;
    }

    @Override
    public List<Equipment> getAll(Long typeId) {

        LambdaQueryWrapper<Equipment> wrapper = new LambdaQueryWrapper<>();
        if (typeId != null) {
            wrapper.eq(Equipment::getTypeId, typeId);  // 只查该类型的设备
        }
        // 1. 拿到所有设备
        List<Equipment> equipmentList = equipmentMapper.selectList(wrapper);
        if (equipmentList.isEmpty()) {
            return equipmentList;
        }

        // 2. 收集所有设备ID，一次性查询所有图片
        List<Long> equipmentIds = equipmentList.stream()
                .map(Equipment::getEquipmentId)
                .collect(Collectors.toList());

        QueryWrapper<EquipmentImage> imageWrapper = new QueryWrapper<>();
        imageWrapper.in("equipment_id", equipmentIds)
                .orderByDesc("sort");

        // 一次性查询所有相关图片
        List<EquipmentImage> allImages = equipmentImageMapper.selectList(imageWrapper);

        // 3. 将图片按设备ID分组，便于快速查找
        Map<Long, List<EquipmentImage>> imageMap = allImages.stream()
                .collect(Collectors.groupingBy(EquipmentImage::getEquipmentId));

        // 4. 为每个设备设置图片
        for (Equipment equipment : equipmentList) {
            // 从Map中获取当前设备的图片列表（不存在则为空列表）
            List<EquipmentImage> images = imageMap.getOrDefault(equipment.getEquipmentId(), Collections.emptyList());
            equipment.setEquipmentImages(images);
        }
        return equipmentList;
    }
    //根据设备ID查询设备，图片视频
    @Override
    public Equipment getByIdImageV(Long id) {
        Equipment equipment = equipmentMapper.selectById(id);
        if (equipment == null) {
            return null;
        }
            // 3. 查询设备图片（非空处理：null转为空集合）
            List<EquipmentImage> images = equipmentImageMapper.selectList(
                    Wrappers.lambdaQuery(EquipmentImage.class)
                            .eq(EquipmentImage::getEquipmentId, id)
            );
            equipment.setEquipmentImages(CollectionUtils.isEmpty(images) ? Collections.emptyList() : images);

            // 4. 查询设备视频（允许为null，直接设置）
            EquipmentVideo video = equipmentVideoMapper.selectOne(
                    Wrappers.lambdaQuery(EquipmentVideo.class)
                            .eq(EquipmentVideo::getEquipmentId, id)
            );
            equipment.setEquipmentVideo(video);

        return equipment;
    }

    //会拿到一堆图片地址和设备信息，先将设备普通添加，再拿到设备id，设置图片视频
    @Override
    public Equipment addImageV(Equipment equipment) {
        //添加应该做一些处理

        //在审核状态那边我已经设置为0了，现在需要加
        if (equipmentMapper.insert(equipment) > 0) {
            //添加成功后拿到设备id
            Long equipmentId = equipment.getEquipmentId();
            //拿到图片列表
            List<EquipmentImage> equipmentImages = equipment.getEquipmentImages();
            //拿到视频列表
           EquipmentVideo videos = equipment.getEquipmentVideo();
            //判断图片列表是否为空
            //设置图片与视频的设备id，保存直接退出，在controller里面进行添加
            if (equipmentImages != null && !equipmentImages.isEmpty()) {
                //遍历图片列表，设置设备id
                for (EquipmentImage equipmentImage : equipmentImages) {
                    equipmentImage.setEquipmentId(equipmentId);
                }
                //将图片列表设置给设备
                equipment.setEquipmentImages(equipmentImages);
            }
            //判断视频列表是否为空
            if (videos != null) {
                    videos.setEquipmentId(equipmentId);
                equipment.setEquipmentVideo(videos);
            }
            return equipment;
        }
        return  null;
    }

    /**
     * 审核设备
     * @param id 设备id
     * @param auditVo 审核信息
     * @return 审核结果
     */
    @Override
    public boolean audit(Long id, AuditVo auditVo) {
        Equipment equipment = equipmentMapper.selectById(id);
        if (equipment != null) {
            equipment.setStatus(auditVo.getStatus());
            equipment.setAuditTime(LocalDateTime.now());
            return equipmentMapper.updateById(equipment) > 0;
        }
        return false;
    }
    private List<Long> getAllChildTypeIds(Long parentId) {
        List<Long> typeIds = new ArrayList<>();
        typeIds.add(parentId);
        QueryWrapper<EquipmentType> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", parentId);
        List<EquipmentType> childTypes = equipmentTypeService.list(wrapper);
        for (EquipmentType child : childTypes) {
            typeIds.addAll(getAllChildTypeIds(child.getTypeId()));
        }
        return typeIds;
    }

    @Override
    public List<Equipment> queryEquipment(EquipmentVo vo) {

            System.out.println("开始查询（无分页）");

            QueryWrapper<Equipment> wrapper = new QueryWrapper<>();
            wrapper.eq("status", 1);

            /* ==================== 各种筛选 ==================== */
            // 设备类型（含子类型）
            Long selectedTypeId = vo.getSelectedTypeId();
            if (selectedTypeId != null && selectedTypeId > 0) {
                List<Long> allTypeIds = getAllChildTypeIds(selectedTypeId);
                if (!allTypeIds.isEmpty()) {
                    wrapper.in("type_id", allTypeIds);
                }
            }

            // 型号
            if (vo.getModel() != null && !vo.getModel().isEmpty()) {
                wrapper.in("model", vo.getModel());
            }

            // 品牌
        if (vo.getBrand() != null && !vo.getBrand().isEmpty()) {
            wrapper.in("brand", vo.getBrand());
        }

            // 价格区间
            if (vo.getMinPrice() != null) {
                wrapper.ge("price", vo.getMinPrice());
            }
            if (vo.getMaxPrice() != null) {
                wrapper.le("price", vo.getMaxPrice());
            }

            // 省份
        if (vo.getLocation() != null && !vo.getLocation().isEmpty()) {
            wrapper.and(w -> {
                for (String province : vo.getLocation()) {
                    w.or().like("location", province + "%");
                }
            });
        }

            // 发布时间区间
            List<String> timeRanges = vo.getTimeRange();
            if (timeRanges != null && !timeRanges.isEmpty()) {
                LocalDateTime endTime = LocalDateTime.now();
                wrapper.and(w -> {
                    for (String timeRangeValue : timeRanges) {
                        LocalDateTime startTime = null;
                        boolean isOverThreeMonths = false;
                        switch (timeRangeValue) {
                            case EquipmentVo.TimeRange.ONE_DAY:
                                startTime = endTime.minusDays(1);
                                break;
                            case EquipmentVo.TimeRange.THREE_DAYS:
                                startTime = endTime.minusDays(3);
                                break;
                            case EquipmentVo.TimeRange.ONE_WEEK:
                                startTime = endTime.minusWeeks(1);
                                break;
                            case EquipmentVo.TimeRange.ONE_MONTH:
                                startTime = endTime.minusMonths(1);
                                break;
                            case EquipmentVo.TimeRange.THREE_MONTHS:
                                startTime = endTime.minusMonths(3);
                                break;
                            case EquipmentVo.TimeRange.MORE_THAN_THREE_MONTHS:
                                startTime = endTime.minusMonths(3);
                                isOverThreeMonths = true;
                                break;
                            default:
                                continue;
                        }
                        if (startTime != null) {
                            if (isOverThreeMonths) {
                                w.or().le("release_time", startTime);
                            } else {
                                w.or().ge("release_time", startTime);
                            }
                        }
                    }
                });
            }

            /* ==================== 排序 ==================== */
            if (!StringUtils.isEmpty(vo.getSortType())) {
                switch (vo.getSortType()) {
                    case EquipmentVo.SortType.PRICE_ASC:
                        wrapper.orderByAsc("price");
                        break;
                    case EquipmentVo.SortType.PRICE_DESC:
                        wrapper.orderByDesc("price");
                        break;
                    case EquipmentVo.SortType.TIME_DESC:
                        wrapper.orderByDesc("release_time");
                        break;
                    case EquipmentVo.SortType.TIME_ASC:
                        wrapper.orderByAsc("release_time");
                        break;
                    case EquipmentVo.SortType.HOUR_ASC:
                        wrapper.orderByAsc("hour");
                        break;
                    case EquipmentVo.SortType.HOUR_DESC:
                        wrapper.orderByDesc("hour");
                        break;
                    case EquipmentVo.SortType.YEAR_ASC:
                        wrapper.orderByAsc("year");
                        break;
                    case EquipmentVo.SortType.YEAR_DESC:
                        wrapper.orderByDesc("year");
                        break;
                    default:
                        wrapper.orderByDesc("create_time");
                }
            } else {
                wrapper.orderByDesc("create_time");
            }

            /* ==================== 查询 ==================== */
            List<Equipment> equipment = list(wrapper);

            /* ==================== 组装附加字段 ==================== */
            for (Equipment e : equipment) {
                // 类型名称
                EquipmentType type = equipmentTypeService.getById(e.getTypeId());
                e.setTypeName(type == null ? null : type.getTypeName());

                // 首张图片
                List<EquipmentImage> imgs = equipmentImageService.list(
                        new QueryWrapper<EquipmentImage>().eq("equipment_id", e.getEquipmentId()));
                if (!imgs.isEmpty()) {
                    e.setImageUrl(imgs.get(0).getImageUrl());
                }

                // 首个视频
                List<EquipmentVideo> videos = equipmentVideoService.list(
                        new QueryWrapper<EquipmentVideo>().eq("equipment_id", e.getEquipmentId()));
                if (!videos.isEmpty()) {
                    e.setVideoUrl(videos.get(0).getVideoUrl());
                }
            }

            System.out.println("查询到的结果（无分页）= " + equipment);
            return equipment;
        }


    @Override
    public List<Equipment> getEqByUserId(Long userId) {
        if (userId == null){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Equipment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Equipment::getUserId, userId);
        List<Equipment> list = equipmentMapper.selectList(wrapper);
        if (list == null){
            return new ArrayList<>();
        }
        //封装视频与图片
        for (Equipment equipment : list) {
            if (equipment == null) {
                return new ArrayList<>();
            }
            //根据设备ID去查询订单表，再将订单表封装进去
            LambdaQueryWrapper<Order> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Order::getEquipmentId, equipment.getEquipmentId());
            Order order = orderService.getOne(wrapper1);
            equipment.setOrder(order);
            // 3. 查询设备图片（非空处理：null转为空集合）
            List<EquipmentImage> images = equipmentImageMapper.selectList(
                    Wrappers.lambdaQuery(EquipmentImage.class)
                            .eq(EquipmentImage::getEquipmentId, equipment.getEquipmentId())
            );
            equipment.setEquipmentImages(CollectionUtils.isEmpty(images) ? Collections.emptyList() : images);

            // 4. 查询设备视频（允许为null，直接设置）
            EquipmentVideo video = equipmentVideoMapper.selectOne(
                    Wrappers.lambdaQuery(EquipmentVideo.class)
                            .eq(EquipmentVideo::getEquipmentId,  equipment.getEquipmentId())
            );
            equipment.setEquipmentVideo(video);

        }
        return list;
    }

    @Override
    public Equipment queryEquipmentAndImageAndType2(Long equipmentId) {
        // 1. 基础信息
        Equipment equipment = getById(equipmentId);
        if (equipment == null) {
            return null;
        }

        // 2. 类型名称
        EquipmentType type = equipmentTypeService.getById(equipment.getTypeId());
        if (type != null) {
            equipment.setTypeName(type.getTypeName());
        }

        // 3. 首张图片
        List<EquipmentImage> imgs = equipmentImageService.list(
                new LambdaQueryWrapper<EquipmentImage>()
                        .eq(EquipmentImage::getEquipmentId, equipmentId)
                        .last("LIMIT 1"));
        if (!imgs.isEmpty()) {
            equipment.setImageUrl(imgs.get(0).getImageUrl());
        }

        // 4. 首个视频（可选）
        List<EquipmentVideo> videos = equipmentVideoService.list(
                new LambdaQueryWrapper<EquipmentVideo>()
                        .eq(EquipmentVideo::getEquipmentId, equipmentId)
                        .last("LIMIT 1"));
        if (!videos.isEmpty()) {
            equipment.setVideoUrl(videos.get(0).getVideoUrl());
        }

        return equipment;
    }

    @Override
    public int getTodayDeviceCount() {
        return equipmentMapper.getTodayDeviceCount();
    }

    @Override
    public int shelf(int equipmentId, EqVo vo) {
        Equipment equipment = equipmentMapper.selectById(equipmentId);
        if (equipment != null) {
            equipment.setStatus(Math.toIntExact(vo.getStatus()));
            return equipmentMapper.updateById(equipment);
        }
        return 0;
    }
}
